<?php
#############################################################################
# Library with all functions needed to connect rodnoe.tv.                   #
# These functions allow to log on to rodnoe.tv, get information about       #
# available channels and to get the channels URLs themselves.               #
#                                                                           #
# Author: consros 2010                                                      #
#############################################################################

require_once("lightJSON.inc");

define("BASE_URL", "core.rodnoe.tv");
define("IDN", 1);

define("SID", "RtvSid");
define("UID", "RtvUid");
define("TO",  "RtvTo");

class RtvFunctions {
    var $traces;
    var $user;
    var $pass;
    var $sid;
    var $uid;
    var $to;

    function RtvFunctions($traces = false) {
        $this->traces = $traces;
        $this->sid    = isset($_SESSION[SID]) ? $_SESSION[SID] : "";
        $this->uid    = isset($_SESSION[UID]) ? $_SESSION[UID] : "";
        $this->to     = isset($_SESSION[TO])  ? $_SESSION[TO]  : "";

        if (is_readable("auth.ini")) {
            $ini_array    = parse_ini_file("auth.ini");
            $this->user   = $ini_array['user'];
            $this->pass   = $ini_array['pass'];
        } else {
            $this->user   = "demo";
            $this->pass   = "demo";
        }
    }

    function forgetSessionId() {
        $_SESSION[SID] = "";
        $_SESSION[UID] = "";
        $_SESSION[TO]  = "";
        $this->sid = "";
        $this->uid = "";
        $this->to  = "";
    }

    function trace($msg) {
        if ($this->traces) {
            print "DEBUG: " . $this->user . ": $msg\n";
        }
    }

    function authorize() {
        $this->trace("Authorization started");

        # Step 1 of 3: get DIV
        $params = $this->sendRequest("/tv_root.php?cmd=get_div&idn=".IDN);
        if (isset($params['err']) && "" != $params['err']) {
            die($this->user . ": wrong user data");
        }
        $div = $params['div'];
        $this->trace("Key: " . $this->user . $div . $this->pass);
        $key = md5($this->user . $div . $this->pass);

        # Step 2 of 3: send authentication data
        $params = $this->sendRequest("/tv_root.php?cmd=auth&idn=".IDN."&key=$key");
        if (isset($params['err']) && "" != $params['err']) {
            die($this->user . ": wrong user data");
        }
        $this->uid = $params['uid'];
        $this->to  = $params['to'];

        # Step 3 of 3: session id reading
        $url = "/tv_root.php?cmd=get_init&idn=".IDN."&uid=$this->uid&to=$this->to";
        $params = $this->sendRequest($url);
        if (isset($params['err']) && "" != $params['err']) {
            die($this->user . ": wrong user data");
        }
        $this->sid = $params['sid'];

        $this->trace("Authorization returned: $this->sid");
        $_SESSION[SID] = $this->sid;
        $_SESSION[UID] = $this->uid;
        $_SESSION[TO]  = $this->to;
    }

    function isAuthorized($params = null) {
        $ok = (! isset($params['err']) || "" == $params['err']) &&
            isset($this->sid) && "" != $this->sid &&
            isset($this->uid) && "" != $this->uid &&
            isset($this->to)  && "" != $this->to;
        if (! $ok) {
            $this->trace("Authorization missed or lost");
        }
        return $ok;
    }

    function getChannelsList() {
        if (! $this->isAuthorized()) {
            $this->authorize();
        }
        $url = "/tv_root.php?cmd=tv_list&idn=".IDN."&uid=$this->uid&to=$this->to";
        $params = $this->sendRequest($url);
        if (! $this->isAuthorized($params)) {
            $this->authorize();
        } else {
            return $params;
        }
        $url = "/tv_root.php?cmd=tv_list&idn=".IDN."&uid=$this->uid&to=$this->to";
        return $this->sendRequest($url);
    }

    function getStreamUrl($alias) {
        $this->trace("Getting URL of stream $alias");
        if (! $this->isAuthorized()) {
            $this->authorize();
        }

        # old way:
        # http://core.rodnoe.tv/go.php?t=ru-znanie&k=$sid
        # return "http://" . BASE_URL . "/go.php?t=$alias&k=$this->sid";

        # new way:
        # http://core.rodnoe.tv/get.php?ch=t+od-ru-ort+$sid
        return "http://" . BASE_URL . "/get.php?ch=t+$alias+$this->sid";
    }

    function getEpg($id, $date = null) {
        # date format is yyyy-mm-dd: 2010-09-20
        # NOTE: at 03:00 starts another EPG day
        $date = date('Y-m-d', $date);
        $timeZone = 60;

        if (! $this->isAuthorized()) {
            $this->authorize();
        }

        # "/tv_root.php?cmd=get_epg_ch&idn=1&uid=XXX"
        # "&ch_id=66&day=2010-11-21&tzo=60"
        $url  = "/tv_root.php?cmd=get_epg_ch&idn=".IDN."&uid=$this->uid";
        $url .= "&ch_id=$id&day=$date&tzo=$timeZone";
        $params = $this->sendRequest($url);
        if (! $this->isAuthorized($params)) {
            $this->authorize();
        } else {
            return $params;
        }
        $url  = "/tv_root.php?cmd=get_epg_ch&idn=".IDN."&uid=$this->uid";
        $url .= "&ch_id=$id&day=$date&tzo=$timeZone";
        return $this->sendRequest($url);
    }

    function sendRequest($url) {
        # try to connect to host
        $fp = fsockopen(BASE_URL, 80, $errno, $errstr, 30);
        if (! $fp) {
            return array('err' => 'NO_CONNECTION');
        }

        # generate request
        $request = "GET $url HTTP/1.1\r\n" .
            "Host: " . BASE_URL . "\r\n" .
            "User-Agent: Mozilla/5.0 (PCH & XTR plugin by consros)\r\n".
            "Accept: application/json, text/javascript, */*\r\n".
            "Content-Type: application/x-www-form-urlencoded\r\n".
            "Connection: close\r\n".
            "X-Requested-With: XMLHttpRequest\r\n\r\n";
        $this->trace("===>$request\n\n");

        # send request and read response
        fwrite($fp, $request);
        $response = "";
        while (! feof($fp)) {
            $response .= fgets($fp, 1024);
        }
        fclose($fp);

        $this->trace("<===$response\n\n");

        # cut json object
        $response = substr($response, strpos($response, '{'));
        $response = substr($response, 0, strrpos($response, '}') + 1);

        # correct some weired response corruption coming with channels list
        $response = preg_replace('|\r\n[A-Za-z0-9]{1,4}\r\n|', '', $response);

        # exclude any new lines
        $response = str_replace(array("\r", "\n"), '', $response);

        $params = json_decode($response, true);
        return null != $params ? $params : array('err' => 'JSON_ERROR_SYNTAX');
    }
}
?>
